/*  

Cafechess Library: Cover basic chess programming needs, like GUI, Engine integration, 
FEN and PGN parsing.

                 \\|//
                 (o o)
--------------ooO-(_)-Ooo----------------------------------
Copyright (C) 2009  By Gregory A. Prentice Snoqualmie, WA
                    www.cafechess.org
                    cafechess@comcast.net
                      Oooo
--------------oooO----(  )---------------------------------
              (  )    (_/
               \_)

Microsoft Public License (Ms-PL)
               
Revisions:

Author        Date    Description:

*/

using System;
using System.IO;
namespace Cafechess.IO
{
  public class DirectoryWalker
  {
    string coDirectoryName;
    string coDirectoryPattern;
    string coFilePattern;
    bool coRecursive;
    bool coFinished;
    bool coCancel;
    public delegate void FoundFile(string fileName);
    public event FoundFile FoundFileEvent;
    public delegate void FoundDirectory(string directoryName);
    public event FoundDirectory FoundDirectoryEvent;
    public delegate void FinishedSearch();
    public event FinishedSearch FinishedSearchEvent;

    public string DirectoryName
    {
      get{return coDirectoryName;}
      set{coDirectoryName = value;}
    }
    public string DirectoryPattern
    {
      get{return coDirectoryPattern;}
      set{ coDirectoryPattern = value;}
    }
    public string FilePattern
    {
      get{return coFilePattern;}
      set{coFilePattern = value;}
    }
    public bool Recursive
    {
      get{return coRecursive;}
      set{coRecursive = value;}
    }
    public bool Cancel
    {
      get { return coCancel; }
      set { coCancel = value; }
    }
    public bool Finished
    {
      get { return coFinished; }
      set { coFinished = value; }
    }

    public DirectoryWalker()
    {
      DirectoryName = System.IO.Path.DirectorySeparatorChar.ToString();
      DirectoryPattern = null;
      FilePattern = "*.*";
      Recursive = false;
      Cancel = false;
    }

    void Search(string directoryName)
    {
      try
      {
        // Find files in the current directory.
        SearchFiles(directoryName);
        if (Recursive && Cancel == false)
        {
          foreach (string d in Directory.GetDirectories(directoryName))
          {
            if (FoundDirectoryEvent != null)
              FoundDirectoryEvent(d);
            SearchFiles(d);
            if (Cancel == true)
              break;
            Search(d);
          }
        }
      }
      catch (System.Exception excpt)
      {
        Console.WriteLine(excpt.Message);
      }
    }

    void SearchFiles(string directoryName)
    {
      if (Cancel == false)
      {
        foreach (string f in Directory.GetFiles(directoryName, FilePattern))
        {
          if (FoundFileEvent != null)
            FoundFileEvent(f);
          if (Cancel == true)
            break;
        }
      }
    }

    public void Search()
    {
      Finished = false;
      Search(DirectoryName);
      Cancel = false;
      Finished = true;
      if (FinishedSearchEvent != null)
        FinishedSearchEvent();
    }     

    public void Search(string filename, bool recursive)
    {
      DirectoryName = System.IO.Path.GetDirectoryName(filename);
      FilePattern = System.IO.Path.GetFileName(filename);
      Search();
    }
    public void AddEvents(IDirectoryWalkerEvents ie)
    {
      FoundFileEvent += new DirectoryWalker.FoundFile(ie.FoundFile);
      FoundDirectoryEvent += new FoundDirectory(ie.FoundDirectory);
      FinishedSearchEvent += new FinishedSearch(ie.FinishedSearch);
    }
    public void RemoveEvents(IDirectoryWalkerEvents ie)
    {
      FoundFileEvent -= new DirectoryWalker.FoundFile(ie.FoundFile);
      FoundDirectoryEvent -= new FoundDirectory(ie.FoundDirectory);
      FinishedSearchEvent -= new FinishedSearch(ie.FinishedSearch);
    }

    public interface IDirectoryWalkerEvents
    {
      void FoundFile(string filename);
      void FoundDirectory(string directoryName);
      void FinishedSearch();
    }
  }
}
